package com.baijiayun.live.ui.chat

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import android.widget.PopupWindow
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.baijiayun.live.ui.DatabindingUtils
import com.baijiayun.live.ui.R
import com.baijiayun.live.ui.atMostViewSize
import com.baijiayun.live.ui.base.RouterViewModel
import com.baijiayun.live.ui.getScreenHeight
import com.baijiayun.live.ui.utils.ColorUtil
import com.baijiayun.livecore.context.LPConstants
import com.baijiayun.livecore.models.LPUserModel
import com.baijiayun.liveuibase.base.BaseAdapter
import com.baijiayun.liveuibase.base.ViewHolder
import com.baijiayun.liveuibase.utils.DisplayUtils
import com.baijiayun.liveuibase.utils.ShadowUtil
import com.baijiayun.liveuibase.utils.ThemeDataUtil
import com.baijiayun.liveuibase.widgets.dialog.ThemeMaterialDialogBuilder
import kotlinx.android.synthetic.main.item_pad_chat.view.*
import kotlinx.android.synthetic.main.layout_menu_opt_header.view.*
import java.util.*

class ChatOptMenuHelper {
    companion object {
        private const val MARGIN = 10
        private const val FORBID_CHAT_DURATION = 24 * 3600L
        private const val ALLOW_CHAT_DURATION = -1L

        /**
         * 1).弹出用户选项菜单
         * 1.无论向上还是向下弹出都保留一定的间距
         * 2.优先向下弹出，其次向上，都不满足向左弹出
         * 2).邀请发言和强制发言有配置项读取
         * 1.邀请发言3个状态 邀请发言 取消邀请 终止发言（邀请发言后30s超时自动发送取消请求）
         * 2.强制发言2个状态 强制发言 终止发言
         * 3.终止发言的判断条件是用户音视频关闭
         */
        @SuppressLint("SetTextI18n")
        fun showOptMenu(context: Context?, routerViewModel: RouterViewModel, view: View, lpUserModel: LPUserModel, fromChat: Boolean = false) {
            if (context == null) {
                return
            }
            if (context is Activity && (context.isDestroyed || context.isFinishing)) {
                return
            }
            if (routerViewModel.liveRoom.currentUser == lpUserModel) {
                return
            }
            if (routerViewModel.liveRoom.currentUser.type == LPConstants.LPUserType.Student || routerViewModel.liveRoom.currentUser.type == LPConstants.LPUserType.Visitor) {
                return
            }
            val items = ArrayList<String>()
            val enableChat = routerViewModel.chatLabelVisiable
            val enablePrivateChat = routerViewModel.liveRoom.chatVM.isLiveCanWhisper
            val isClassStarted = routerViewModel.isClassStarted.value == true
            if(isClassStarted) {
                //老师可以指定非主讲的助教为主讲
                if(routerViewModel.liveRoom.currentUser.type == LPConstants.LPUserType.Teacher && lpUserModel.type == LPConstants.LPUserType.Assistant && !routerViewModel.liveRoom.speakQueueVM.isPresenterUser(lpUserModel)) {
                    items.add(context.getString(R.string.live_set_to_presenter))
                }
                //当前用户是助教&主讲&开启配置项，可以指定其它助教为主讲
                if(routerViewModel.liveRoom.currentUser.type == LPConstants.LPUserType.Assistant && routerViewModel.liveRoom.partnerConfig.enableAssistantTurnPresenter && routerViewModel.liveRoom.speakQueueVM.isPresenterUser(routerViewModel.liveRoom.currentUser)
                        && lpUserModel.type == LPConstants.LPUserType.Assistant) {
                    items.add(context.getString(R.string.live_set_to_presenter))
                }
                //老师可以收回主讲
                if(routerViewModel.liveRoom.currentUser.type == LPConstants.LPUserType.Teacher && routerViewModel.liveRoom.speakQueueVM.isPresenterUser(lpUserModel)) {
                    items.add(context.getString(R.string.live_unset_presenter))
                }
            }
            if (lpUserModel.type == LPConstants.LPUserType.Assistant || lpUserModel.type == LPConstants.LPUserType.Teacher) {
                if (enableChat && enablePrivateChat) {
                    items.add(context.getString(R.string.live_private_chat))
                }
            } else {
                if (isClassStarted && routerViewModel.liveRoom.hasStudentRaise() &&(!routerViewModel.liveRoom.isPushLive && !routerViewModel.liveRoom.isMockLive)) {
                    items.add(getSpeakItem(context, routerViewModel, lpUserModel))
                }
                if (enableChat) {
                    val enableForbidAndKick = routerViewModel.liveRoom.currentUser.type == LPConstants.LPUserType.Teacher ||
                            (routerViewModel.liveRoom.currentUser.type == LPConstants.LPUserType.Assistant && routerViewModel.liveRoom.adminAuth.forbidAndKick)
                    if (enableForbidAndKick) {
                        if (routerViewModel.forbidChatUserNums.contains(lpUserModel.number)) {
                            items.add(context.getString(R.string.live_allow_chat))
                        } else {
                            items.add(context.getString(R.string.live_forbid_chat))
                        }
                    }
                    if (enablePrivateChat) {
                        items.add(context.getString(R.string.live_private_chat))
                    }
                }
            }
            if (items.isEmpty()) {
                return
            }
            val popupWindow = PopupWindow(context)
            popupWindow.isFocusable = true
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                popupWindow.elevation = 2.0f
            }
            popupWindow.setBackgroundDrawable(ColorDrawable(0))
            popupWindow.width = context.resources.getDimensionPixelSize(R.dimen.main_video_menu_width)
            popupWindow.height = ViewGroup.LayoutParams.WRAP_CONTENT
            val bgDrawable = GradientDrawable()
            bgDrawable.setColor(ThemeDataUtil.getColorFromThemeConfigByAttrId(context, R.attr.base_theme_window_bg_color))
            bgDrawable.setStroke(1, ContextCompat.getColor(context, R.color.base_bg_stroke))
            bgDrawable.cornerRadius = context.resources.getDimensionPixelSize(R.dimen.bjy_base_common_bg_radius).toFloat()
            val listView = ListView(context)
            val headerView = View.inflate(context, R.layout.layout_menu_opt_header, null)
            DatabindingUtils.loadImg(headerView.userAvatar, lpUserModel.avatar)
            when (lpUserModel.type) {
                LPConstants.LPUserType.Teacher -> {
                    if (fromChat) {
                        headerView.userRole.visibility = View.GONE
                        headerView.userName.text = "${lpUserModel.name}[${context.getString(R.string.live_teacher)}]"
                    } else {
                        headerView.userRole.visibility = View.VISIBLE
                        headerView.userRole.text = context.getString(R.string.live_teacher)
                        headerView.userRole.setTextColor(ThemeDataUtil.getColorFromThemeConfigByAttrId(context, R.attr.base_theme_live_product_color))
                        headerView.userRole.background = ThemeDataUtil.getUserTagBg(context)
                        headerView.userName.text = lpUserModel.name
                    }
                }
                LPConstants.LPUserType.Assistant -> {
                    val color = ColorUtil.getColor(lpUserModel.number)
                    headerView.userAvatar.setCircleBackgroundColor(Color.HSVToColor(color))
                    if (fromChat) {
                        headerView.userRole.visibility = View.GONE
                        headerView.userName.text = "${lpUserModel.name}[${context.getString(R.string.live_assistent)}]"
                    } else {
                        headerView.userRole.visibility = View.VISIBLE
                        headerView.userRole.text = context.getString(R.string.live_assistent)
                        headerView.userRole.setTextColor(ContextCompat.getColor(context, R.color.live_pad_orange))
                        headerView.userRole.background = ContextCompat.getDrawable(context, R.drawable.item_online_user_assistant_bg)
                        headerView.userName.text = lpUserModel.name
                    }
                }
                else -> {
                    headerView.userRole.visibility = View.GONE
                    headerView.userName.text = lpUserModel.name
                }
            }
            listView.addHeaderView(headerView)
            listView.setOnItemClickListener { _, _, position, _ ->
                if (position == 0) {
                    return@setOnItemClickListener
                }
                when (items[position - 1]) {
                    context.getString(R.string.live_force_speak) -> {
                        routerViewModel.liveRoom.speakQueueVM.controlRemoteSpeak(lpUserModel.userId, true, true)
                    }
                    context.getString(R.string.live_invite_speak) -> {
                        if (routerViewModel.liveRoom.speakQueueVM.sendSpeakInviteReq(lpUserModel.userId, true)) {
                            routerViewModel.invitingUserIds.add(lpUserModel.userId)
                            routerViewModel.timeOutStart.value = lpUserModel.userId to true
                        }
                    }
                    context.getString(R.string.live_invite_cancel) -> {
                        if (routerViewModel.liveRoom.speakQueueVM.sendSpeakInviteReq(lpUserModel.userId, false)) {
                            routerViewModel.invitingUserIds.remove(lpUserModel.userId)
                            routerViewModel.timeOutStart.value = lpUserModel.userId to false
                        }
                    }
                    context.getString(R.string.live_end_speak) -> {
                        routerViewModel.liveRoom.speakQueueVM.closeOtherSpeak(lpUserModel.userId)
                    }
                    context.getString(R.string.live_allow_chat) -> {
                        routerViewModel.liveRoom.forbidChat(lpUserModel, ALLOW_CHAT_DURATION)
                    }
                    context.getString(R.string.live_forbid_chat) -> {
                        routerViewModel.liveRoom.forbidChat(lpUserModel, FORBID_CHAT_DURATION)
                    }
                    context.getString(R.string.live_private_chat) -> {
                        routerViewModel.privateChatUser.value = lpUserModel
                        routerViewModel.actionShowSendMessageFragment.value = ""
                    }
                    context.getString(R.string.base_ui_kickout_room) -> {
                        showKickOutDlg(context, routerViewModel, lpUserModel)
                    }
                    context.getString(R.string.live_set_to_presenter) -> {
                        routerViewModel.liveRoom.speakQueueVM.requestSwitchPresenter(lpUserModel.userId)
                    }
                    context.getString(R.string.live_unset_presenter) -> {
                        routerViewModel.liveRoom.speakQueueVM.requestSwitchPresenter(routerViewModel.liveRoom.currentUser.userId)
                    }
                }
                popupWindow.dismiss()
            }
            listView.background = bgDrawable
            listView.adapter = object : BaseAdapter<String>(context, R.layout.bjy_menu_chat_opt, items) {
                override fun convert(helper: ViewHolder, item: String?, position: Int) {
                    val text: TextView = helper.getView(R.id.textView)
                    text.text = item
                    if (item == context.getString(R.string.base_ui_kickout_room)) {
                        text.setTextColor(ContextCompat.getColor(context, R.color.base_warning_color))
                    } else {
                        text.setTextColor(ThemeDataUtil.getColorFromThemeConfigByAttrId(context, R.attr.base_theme_live_product_color))
                    }
                }
            }
            listView.divider = ColorDrawable(ContextCompat.getColor(context, R.color.base_divider_line_other))
            listView.dividerHeight = DisplayUtils.dip2px(context, 1f)
            listView.setPadding(0, DisplayUtils.dip2px(context, 2f), 0, DisplayUtils.dip2px(context, 2f))
            val shadowGroup = ShadowUtil.initShadowView(context, listView)
            shadowGroup?.let {
                if (it.shadowContainer != null) {
                    ShadowUtil.setViewBoundShadow(it.shadowContainer)
                }
                popupWindow.contentView = it.contentView
                val measuredHeight = atMostViewSize(listView)[1]
                val location = IntArray(2)
                view.getLocationOnScreen(location)
                val screenHeight = getScreenHeight(context)
                val maxAvailableHeight = screenHeight - location[1] - view.height
                when {
                    maxAvailableHeight > measuredHeight + MARGIN -> {
                        popupWindow.showAsDropDown(view)
                    }
                    location[1] > measuredHeight + MARGIN -> {
                        //向上弹出
                        popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0], location[1] - measuredHeight)
                    }
                    else -> {
                        //向左弹出
                        popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0] - popupWindow.width, location[1] - measuredHeight / 2)
                    }
                }
            }
        }

        /**
         * 主动踢人
         */
        private fun showKickOutDlg(context: Context, routerViewModel: RouterViewModel, lpUserModel: LPUserModel) {
            if (context is Activity && (context.isDestroyed || context.isFinishing)) {
                return
            }
            ThemeMaterialDialogBuilder(context)
                    .apply {
                        title("您确定将\"${lpUserModel.name}\"踢出教室？")
                        content(context.getString(R.string.live_pad_kickout_tip))
                    }
                    .apply {
                        positiveText(context.getString(R.string.live_pad_kickout))
                        positiveColorRes(R.color.base_warning_color)
                        onPositive { _, _ ->
                            routerViewModel.liveRoom.requestKickOutUser(lpUserModel.userId)
                        }
                    }
                    .apply {
                        negativeText(context.getString(R.string.live_cancel))
                    }
                    .build().show()
        }

        /**
         * 强制发言和邀请发言的item
         */
        private fun getSpeakItem(context: Context, routerViewModel: RouterViewModel, lpUserModel: LPUserModel): String =
                //强制发言
                if (routerViewModel.liveRoom.partnerConfig.inviteSpeakType == 1) {
                    val lpMediaModel = routerViewModel.liveRoom.player.chmUserMediaModel[lpUserModel.userId]
                    if (lpMediaModel?.videoOn == true || lpMediaModel?.audioOn == true) {
                        context.getString(R.string.live_end_speak)
                    } else {
                        context.getString(R.string.live_force_speak)
                    }
                } else {
                    val lpMediaModel = routerViewModel.liveRoom.player.chmUserMediaModel[lpUserModel.userId]
                    if (lpMediaModel?.audioOn == true || lpMediaModel?.videoOn == true) {
                        context.getString(R.string.live_end_speak)
                    } else {
                        if (routerViewModel.invitingUserIds.contains(lpUserModel.userId)) {
                            context.getString(R.string.live_invite_cancel)
                        } else {
                            context.getString(R.string.live_invite_speak)
                        }
                    }
                }
    }
}